package com.zlll.winner.service.sysUser;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zlll.winner.business.model.sysUser.SysPermissionRole;
import com.zlll.winner.business.model.sysUser.SysRole;
import com.zlll.winner.business.service.sysUser.ISysPermissionRoleService;
import com.zlll.winner.enums.CommonEnum;
import com.zlll.winner.mapper.sysUser.SysPermissionRoleMapper;
import com.zlll.winner.mapper.sysUser.SysRoleMapper;
import com.zlll.winner.business.service.sysUser.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author ricky
 * @since 2019-09-06
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private ISysPermissionRoleService iSysPermissionRoleService;
    @Autowired
    private SysPermissionRoleMapper sysPermissionRoleMapper;

    /**
     * 查询菜单权限
     * @param role
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public IPage<SysRole> findRolePage(SysRole role, Integer pageNo, Integer pageSize) {
        IPage<SysRole> page = new Page<SysRole>(pageNo,pageSize);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del",CommonEnum.DelEnum.UNDEL.val());
        if(role.getName()!=null && !"".equals(role.getName())){
            queryWrapper.like("name",role.getName());
        }
        queryWrapper.orderBy(true,false,"create_time");
        return sysRoleMapper.selectPage(page, queryWrapper);
    }

    /**
     * 新增角色菜单权限
     * @param role
     * @param menuIds
     * @param userId
     * @param name
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public void addMenuRole(SysRole role, List<Long> menuIds, Long userId, String name) {
        //新增角色信息
        Long roleId = this.addRole(role,userId,name);
        if(CollectionUtils.isNotEmpty(menuIds)) {
            iSysPermissionRoleService.addPermissionRole(menuIds,userId,name,roleId);
        }
    }

    /**
     * 新增角色信息
     * @param role
     * @param userId
     * @param name
     * @return
     */
    public Long addRole(SysRole role, Long userId, String name) {
        hasSameName("add", role);
        role.setCreateUserId(userId);
        role.setCreateUser(name);
        role.setCreateTime(new Date().getTime());
        sysRoleMapper.insert(role);
        return role.getId();
    }

    /**
     * 更新角色
     * @param role
     * @param menuIds
     * @param userId
     * @param name
     */
    @Override
    public void updateMenuRole(SysRole role, List<Long> menuIds, Long userId, String name) {
        // TODO: 2019-09-07 此处需要跟用户role相关
        //更新角色信息
        this.updateRole(role,userId,name);
        Set<Long> menusSet = new HashSet<>(menuIds);
        List<SysPermissionRole> oldPermissionRoles = iSysPermissionRoleService.getPermissionRoleAllList(role.getId());
        if(oldPermissionRoles != null && oldPermissionRoles.size() > 0){
            Set<Long> oldMenuIds = oldPermissionRoles.stream().map(SysPermissionRole::getMenuId).collect(Collectors.toSet());
            Set<Long> updateIds = oldPermissionRoles.stream()
                    .filter(item ->menusSet.contains(item.getMenuId()) && item.getIsDel().equals(CommonEnum.DelEnum.DEL.val()))
                    .map(SysPermissionRole::getId)
                    .collect(Collectors.toSet());
            Set<Long> deleteIds = oldPermissionRoles.stream()
                    .filter(item ->!menusSet.contains(item.getMenuId()) && item.getIsDel().equals(CommonEnum.DelEnum.UNDEL.val()))
                    .map(SysPermissionRole::getId)
                    .collect(Collectors.toSet());

            SysPermissionRole updateObj = new SysPermissionRole();
            updateObj.setUpdateTime(System.currentTimeMillis());
            updateObj.setUpdateUser(name);
            updateObj.setUpdateUserId(userId);

            //启用
            if(updateIds!=null && updateIds.size() > 0) {
                QueryWrapper<SysPermissionRole> updateWrapper = new QueryWrapper<>();
                updateWrapper.in("id", updateIds);
                updateObj.setIsDel(CommonEnum.DelEnum.UNDEL.val());
                sysPermissionRoleMapper.update(updateObj, updateWrapper);
            }
            //删除
            if(deleteIds!=null && deleteIds.size() > 0) {
                QueryWrapper<SysPermissionRole> delWrapper = new QueryWrapper<>();
                delWrapper.in("id", deleteIds);
                updateObj.setIsDel(CommonEnum.DelEnum.DEL.val());
                sysPermissionRoleMapper.update(updateObj, delWrapper);
            }
            //新增PermissionRole
            List<Long> insertMenuIds = menusSet.stream().filter(id->!oldMenuIds.contains(id)).collect(Collectors.toList());
            if(insertMenuIds != null && insertMenuIds.size() > 0) {
                iSysPermissionRoleService.addPermissionRole(insertMenuIds, userId, name, role.getId());
            }
        }else{
            iSysPermissionRoleService.addPermissionRole(menuIds,userId,name,role.getId());
        }
    }

    /**
     * 删除角色
     * @param id
     * @param userId
     * @param name
     */
    @Override
    public void deleteRole(Long id, Long userId, String name) {
        SysRole role = sysRoleMapper.selectById(id);
        role.setUpdateUserId(userId);
        role.setUpdateUser(name);
        role.setUpdateTime(new Date().getTime());
        role.setIsDel(CommonEnum.DelEnum.DEL.val());
        sysRoleMapper.updateById(role);
    }

    /**
     * 获取所有的角色列表
     * @return
     */
    @Override
    public List<SysRole> getAllList() {
        QueryWrapper<SysRole> query = new QueryWrapper<SysRole>();
        query.eq("is_del", CommonEnum.DelEnum.UNDEL.val());
        query.orderBy(true,false,"create_time");
        return sysRoleMapper.selectList(query);
    }

    /**
     * 更新角色
     * @param role
     * @param userId
     * @param name
     */
    public void updateRole(SysRole role, Long userId, String name){
        hasSameName("update", role);
        role.setUpdateUserId(userId);
        role.setUpdateUser(name);
        role.setUpdateTime(new Date().getTime());
        sysRoleMapper.updateById(role);
    }

    /**
     * 判断角色名称是否重复
     * @param action
     * @param role
     */
    private void hasSameName(String action, SysRole role) {
        List<Long> ids = sysRoleMapper.selectRoleByName(role.getName());
        if (!CollectionUtils.isEmpty(ids)) {
            if ("add".equals(action)) {
                Assert.isTrue(false,"权限包已存在");
            } else if ("update".equals(action)) {
                for (Long id : ids) {
                    if (!id.equals(role.getId())) {
                        Assert.isTrue(false,"权限包已存在");
                    }
                }
            }
        }
    }
}
